//
//  SubscribeAction.swift
//  MagaCore
//
//  Created by MrMessy on 2023/5/18.
//

import Foundation
import HandyJSON
import Moya
import PKHUD
import ReSwift
import ReSwiftThunk
import StoreKit
import SwiftyStoreKit

enum HTEnumSubscribeAction: Action {
    case htEnumProductsInfo(var_subscribes: [HTSubscribe]?)
    case htEnumSelSub(var_selSub: HTSubscribe?)
    case htEnumCurSub(var_curSub: HTSubscribe?)
    case htEnumIntroductorySub(var_introductorySub: HTSubscribe?)
    case htEnumSetPurchasingSubscribe(var_purchasingSub: Bool?)

    // 获取订阅可用产品
    static func ht_retrieveProductsInfo() -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            SwiftyStoreKit.retrieveProductsInfo(HTConfig.STATIC_subscribeProductIds) { result in
                var var_products: [Any] = []
                let var_sortOrder: [String] = HTConfig.STATIC_subscribeAscOrder
                for product in result.retrievedProducts {
                    var var_params: [String: Any] = [:]
                    var_params["var_productIdentifier"] = product.productIdentifier
                    var_params["var_subscriptionGroupIdentifier"] = product.subscriptionGroupIdentifier
                    if product.productIdentifier == "week" {
                        var_params["var_title"] = "Weekly"
                        var_params["var_desc"] = "week"
                        var_params["var_origin_price"] = NSDecimalNumber(string: "2.99")
                        var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "7"))
                    } else if product.productIdentifier == "month" {
                        var_params["var_title"] = "Monthly"
                        var_params["var_desc"] = "month"
                        var_params["var_origin_price"] = NSDecimalNumber(string: "9.99")
                        var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "30"))
                    } else if product.productIdentifier == "year" {
                        var_params["var_title"] = "Annually"
                        var_params["var_desc"] = "year"
                        var_params["var_origin_price"] = NSDecimalNumber(string: "109.99")
                        var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "365"))
                        var_params["var_isBestPrice"] = true
                    }
                    var_params["var_price"] = product.price
                    var_params["var_introductoryPrice"] = product.introductoryPrice?.price
                    if let var_unit = product.introductoryPrice?.subscriptionPeriod.unit.rawValue {
                        if var_unit == 0 {
                            var_params["var_introductory_unit"] = "day"
                        } else if var_unit == 1 {
                            var_params["var_introductory_unit"] = "week"
                        } else if var_unit == 2 {
                            var_params["var_introductory_unit"] = "month"
                        } else if var_unit == 3 {
                            var_params["var_introductory_unit"] = "year"
                        }
                    }
                    var_products.append(var_params)
                }
                var var_introductorySub: HTSubscribe = HTSubscribe()
                var var_subscribes = [HTSubscribe].deserialize(from: var_products) as! [HTSubscribe]
                var_subscribes.sort(by: { s1, s2 in
                    if let identifier1 = s1.var_productIdentifier,
                       let identifier2 = s2.var_productIdentifier,
                       let index1 = var_sortOrder.firstIndex(of: identifier1),
                       let index2 = var_sortOrder.firstIndex(of: identifier2) {
                        return index1 < index2
                    }
                    return false
                })
                var_subscribes.sort(by: { s1, _ in
                    s1.var_introductoryPrice != nil
                })

                for subscribe in var_subscribes {
                    if subscribe.var_introductoryPrice != nil {
                        var_introductorySub = subscribe
                        break
                    }
                }

                dispatch(HTEnumSubscribeAction.htEnumIntroductorySub(var_introductorySub: var_introductorySub))
                dispatch(HTEnumSubscribeAction.htEnumProductsInfo(var_subscribes: var_subscribes))
                if let sub = var_subscribes.first {
                    dispatch(ht_selSub(sub: sub))
                }
            }
        }
    }

    // 选择订阅产品
    static func ht_selSub(sub: HTSubscribe) -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            dispatch(HTEnumSubscribeAction.htEnumSelSub(var_selSub: sub))
        }
    }

    // 获取当前订阅的信息
    static func ht_getCurrentSubscriptionInfo(callback: ((HTSubscribe?) -> Void)?) -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            let appleValidator = AppleReceiptValidator(service: HTConfig.STATIC_subscribeService, sharedSecret: HTConfig.STATIC_subscribeSecret)
            SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
                switch result {
                case let .success(receipt):
                    let purchaseResult = SwiftyStoreKit.verifySubscriptions(
                        ofType: .autoRenewable, // or .nonRenewing (see below)
                        productIds: HTConfig.STATIC_subscribeProductIds,
                        inReceipt: receipt)

                    switch purchaseResult {
                    case let .purchased(expiryDate, items):
                        var var_params: [String: Any] = [:]
                        let var_sortOrder: [String] = HTConfig.STATIC_subscribeDescOrder
                        let var_filteredItems = items.filter { $0.subscriptionExpirationDate! > Date() }
                        let var_sortedItems: [ReceiptItem] = var_filteredItems.sorted(by: { s1, s2 in
                            let identifier1 = s1.productId
                            let identifier2 = s2.productId
                            let index1 = var_sortOrder.firstIndex(of: identifier1)
                            let index2 = var_sortOrder.firstIndex(of: identifier2)
                            return index1! < index2!
                        })

                        if let var_curSub = var_sortedItems.first {
                            if var_curSub.productId == "week" {
                                var_params["var_title"] = "Weekly"
                            } else if var_curSub.productId == "month" {
                                var_params["var_title"] = "Monthly"
                            } else if var_curSub.productId == "year" {
                                var_params["var_title"] = "Annually"
                            }
                            var_params["var_expiredDate"] = expiryDate.formatString(dateFormat: "MMM dd,YYYY")
                            let var_curSubscribe = HTSubscribe.deserialize(from: var_params)
                            dispatch(HTEnumSubscribeAction.htEnumCurSub(var_curSub: var_curSubscribe))

                            UserDefaults().set(expiryDate.formatString(dateFormat: "MMM dd,YYYY"), forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
                            HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "1"))
                            dispatch(HTEnumShareAction.ht_shareConfig(var_p1: var_curSub.productId, var_p2: "2"))

//              if let receiptURL = Bundle.main.appStoreReceiptURL {
//                do {
//                        let receiptData = try Data(contentsOf: receiptURL)
//                        let receiptString = receiptData.base64EncodedString(options: .endLineWithLineFeed)
                            let receiptString: String = receipt["latest_receipt"] as? String ?? ""
                            HTNetworkManager().ht_request(.htEnumSubscribeRestore(var_pid: var_curSub.productId, var_receipt: receiptString)) { result in
                                if result.var_status == "200" {
                                    let var_dataDist = result.ht_dataDist()
                                    let var_local: [String: Any] = var_dataDist?["local"] as! [String: Any]
                                    let var_auto_renew_status: Int
                                    if var_local["auto_renew_status"] is Int {
                                        var_auto_renew_status = var_local["auto_renew_status"] as! Int
                                    } else {
                                        var_auto_renew_status = Int(var_local["auto_renew_status"] as! String)!
                                    }
                                    var var_curSubscribe_new = var_curSubscribe
                                    var_curSubscribe_new?.var_auto_renew_status = var_auto_renew_status
                                    dispatch(HTEnumSubscribeAction.htEnumCurSub(var_curSub: var_curSubscribe_new))
                                }
                            }
//                    } catch {
//                        print("无法读取 App Store 凭证文件: \(error.localizedDescription)")
//                    }
//              }

                            if callback != nil {
                                callback!(var_curSubscribe!)
                            }
                        } else {
                            print("没有当前订阅")
                            UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
                            HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
                            if callback != nil {
                                callback!(nil)
                            }
                        }
                    case .expired:
                        UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
                        HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
                        if callback != nil {
                            callback!(nil)
                        }
                    case .notPurchased:
                        UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
                        HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
                        if callback != nil {
                            callback!(nil)
                        }
                    }

                case let .error(error):
                    print("Receipt verification failed: \(error)")
                    UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
                    HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
                    if callback != nil {
                        callback!(nil)
                    }
                }
            }
        }
    }

    // 订阅支付
    static func ht_purchaseProduct(productId: String, andSuccess: (() -> Void)?, andFail: (() -> Void)?) -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            HUD.show(.progress)
            dispatch(ht_setPurchasingSubscribe(var_purchasingSub: true))
            SwiftyStoreKit.purchaseProduct(productId) { result in
                switch result {
                case let .success(purchase):
                    print("Purchase Success: \(purchase.productId)")
                    HUD.hide()

                    if let receiptURL = Bundle.main.appStoreReceiptURL {
                        do {
                            let receiptData = try Data(contentsOf: receiptURL)
                            let receiptString = receiptData.base64EncodedString(options: .endLineWithLineFeed)

                            HTNetworkManager().ht_request(.htEnumSubscribeBind(var_pid: purchase.productId, var_receipt: receiptString)) { result in
                                if result.var_status == "200" {
                                    dispatch(ht_getCurrentSubscriptionInfo(callback: nil))
                                }
                            }
                        } catch {
                            print("无法读取 App Store 凭证文件: \(error.localizedDescription)")
                        }
                    }

                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        dispatch(ht_setPurchasingSubscribe(var_purchasingSub: false))
                    }
                    if andSuccess != nil {
                        andSuccess!()
                    }
                case let .error(error):
                    switch error.code {
                    case .unknown: print("Unknown error. Please contact support")
                    case .clientInvalid: print("Not allowed to make the payment")
                    case .paymentCancelled: break
                    case .paymentInvalid: print("The purchase identifier was invalid")
                    case .paymentNotAllowed: print("The device is not allowed to make the payment")
                    case .storeProductNotAvailable: print("The product is not available in the current storefront")
                    case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
                    case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
                    case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
                    default: print((error as NSError).localizedDescription)
                    }
                    HUD.hide()
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        dispatch(ht_setPurchasingSubscribe(var_purchasingSub: false))
                    }
                    if andFail != nil {
                        andFail!()
                    }
                }
            }
        }
    }

    // 恢复购买
    static func ht_restorePurchases() -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            HUD.show(.progress)
            SwiftyStoreKit.restorePurchases { results in
                HUD.hide()
                if results.restoreFailedPurchases.isEmpty {
                    HUD.flash(.labeledSuccess(title: "", subtitle: "Subscription status updated"), delay: 1.0)
                    // 恢复购买成功
                    print("Restore Success")
                    // 在此处执行相关操作，例如解锁功能或更新用户订阅状态等
                    dispatch(ht_getCurrentSubscriptionInfo(callback: nil))
                } else {
                    HUD.flash(.labeledError(title: "", subtitle: "Subscription status update failed"), delay: 1.0)
                    // 恢复购买失败
                    print("Restore Failed: \(results.restoreFailedPurchases)")
                }
            }
        }
    }

    static func ht_setPurchasingSubscribe(var_purchasingSub: Bool?) -> Thunk<HTAppState> {
        Thunk<HTAppState> { dispatch, _ in
            dispatch(HTEnumSubscribeAction.htEnumSetPurchasingSubscribe(var_purchasingSub: var_purchasingSub))
        }
    }
}
